#include "StdAfx.h"
#include "AdditiveSynth.h"


CAdditiveSynth::CAdditiveSynth(void)
{
	m_amp.clear();
	m_ampfade.clear();
	m_vibrato = false;
	m_vibratofreq = 0.;
	m_modulation = 0.;
	m_time = 0.;
}


CAdditiveSynth::~CAdditiveSynth(void)
{
}

void CAdditiveSynth::Start()
{
    m_phase = 0;
	m_time = 0.;
	m_vibratophase = 0.;
}

bool CAdditiveSynth::Generate()
{
	if(m_ampfade.empty())
	{
		for(unsigned i = 0; i < m_amp.size(); i++)
			m_ampfade.push_back(m_amp[i]);
	}

    double sample = GenerateCrossfade();

    m_frame[1] = m_frame[0] = sample;

	if(m_vibrato)
	{
		m_phase += 2 * PI * (m_freq + m_modulation * sin(m_vibratophase)) * GetSamplePeriod();
		m_vibratophase += 2 * PI * GetSamplePeriod() * m_vibratofreq;
	}
	else
		m_phase += 2 * PI * m_freq * GetSamplePeriod();

	m_time += GetSamplePeriod();

    return true;
}

double CAdditiveSynth::GenerateCrossfade(void)
{
	double sample = 0.;
	double nyquist = GetSampleRate()/2.;

	for(int i=0; i<m_amp.size(); i++)
	{
		if(m_amp[i] * m_freq <= nyquist)
			sample += m_amp[i] * (1 - (m_time/m_duration*(1./(m_bpm/60.)))) * sin(m_phase * (i + 1));
	}
	for(int i=0; i<m_ampfade.size(); i++)
	{
		if(m_ampfade[i] * m_freq <= nyquist)
		{
			sample += m_ampfade[i] * (m_time/m_duration*(1./(m_bpm/60.))) * sin(m_phase * (i + 1));

			//double diff = abs((m_ampfade[i] * (m_time/m_duration) * sin(m_phase * (i + 1))) - sample);
			//if(m_amp[i] > m_ampfade[i])
			//	sample -= diff;
			//else
			//	sample += diff;
		}
	}

	return sample;
}
